package com.mzj.saas.mservice.report.service;


import com.mzj.saas.commons.DataConversionUtil;
import com.mzj.saas.commons.ResultBean;
import com.mzj.saas.commons.vo.redis.TokenRedisVo;
import com.mzj.saas.mservice.eligible.entity.DepartmentEnterpriseTagRef;
import com.mzj.saas.mservice.eligible.entity.DepartmentHierarchy;
import com.mzj.saas.mservice.eligible.repository.DepartmentEnterpriseTagRefRepository;
import com.mzj.saas.mservice.eligible.repository.DepartmentHierarchyRepository;
import com.mzj.saas.mservice.report.entity.ReportPaymentStatistics;
import com.mzj.saas.mservice.report.vo.ReportPaymentStatisticsVO;
import com.mzj.saas.redis.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ReportPaymentStatisticsService {
    /**
     * 在控制台打印日志信息
     */
    private static final Logger log = LoggerFactory.getLogger(ReportPaymentStatisticsService.class);

    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private RedisService redisService;
    @Autowired
    private DepartmentHierarchyRepository departmentHierarchyRepository;
    @Autowired
    private DepartmentEnterpriseTagRefRepository departmentEnterpriseTagRefRepository;

    /**
     * 列表
     * 根据不同的登录用户标签获取不同的缴费总数据
     * @param accessToken 验证令牌
     * @param pageNumber 起始数据
     * @param pageSize 页面大小
     * @param vo 页面数据
     * @return
     */
    public ResultBean<Map<String, Object>> pages(String accessToken, Integer pageNumber, Integer pageSize, ReportPaymentStatisticsVO vo) {
        log.info("ReportPaymentStatisticsService  pages  accessToken={} ,vo={}", accessToken, vo.toString());

        String SQL = " SELECT s.stat_date,s.month_date,SUM(s.already_pay_amount) already_pay_amount,SUM(s.normal_payment_amount) normal_payment_amount,\n" +
                "SUM(s.overdue_payment_amount) overdue_payment_amount,SUM(s.overdue_already_amount) overdue_already_amount \n" +
                "FROM saas_report_payment_statistics s inner join saas_department d on s.house_property_id=d.id  ";

        //获取登录用户信息
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        if (tokenRedisVo == null) {
            //未登录提示异常 40001 --- accessToken失效
            return ResultBean.failedResultOfToken();
        }

        //判断用户所属机构是否设置层级架构
        Long enterpriseId = tokenRedisVo.getEnterpriseId();
        DepartmentHierarchy hierarchy = departmentHierarchyRepository.findByOrgIdAndStatus(enterpriseId, 1);
        if (hierarchy == null) {
            //用户所属机构未设置层级架构 10001 --- 用户所属机构未设置层级架构
            return ResultBean.failedResultWithMsg("用户所属机构未设置层级架构");
        }
        //根据机构层级关系id查出企业与标签关系数据
        Long id = hierarchy.getId();
        List<DepartmentEnterpriseTagRef> refs = departmentEnterpriseTagRefRepository.findByDepRefId(id);
        //去重后的用户企业标签
        List<Long> enterpriseTagIds = refs.stream().map(DepartmentEnterpriseTagRef::getTagId).distinct().collect(Collectors.toList());//用户企业标签

        //1、政府机构，根据区域标签所对应区域id查
        Long areaTagId = hierarchy.getTagId();//区域标签
        Long areaId = null;
        if (enterpriseTagIds.contains(3L)) {
            areaId = hierarchy.getAreaId();//区域id
        }
        /**
         * 根据不同标签查询不同的业务数据
         */
        String areaTag = "";
        if (areaTagId == 1) {
            areaTag = "province_id";
        } else if (areaTagId == 2) {
            areaTag = "city_id";
        } else if (areaTagId == 3) {
            areaTag = "district_id";
        } else if (areaTagId == 4) {
            areaTag = "street_id";
        } else if (areaTagId == 5) {
            areaTag = "community_id";
        }

        //2、物业
        Long hierarchyOrgId = null;
        if (enterpriseTagIds.contains(4L)) {
            hierarchyOrgId = hierarchy.getOrgId();
        }

        StringBuilder where = new StringBuilder(" WHERE 1=1 ");
        List<Object> args = new ArrayList<>();

        where.append(" and ( d." + areaTag + " = ? or s.house_property_id = ? ) ");
        args.add(areaId);
        args.add(hierarchyOrgId);

        if (vo != null) {
            //月份
            if (StringUtils.isNotBlank(vo.getMonthDate())) {
                where.append(" and s.month_date = ?  ");
                args.add(vo.getMonthDate());
            }
        }

        Map<String, Object> map = new HashMap<>();

        where.append(" GROUP BY s.stat_date ");

        //查询
        List<ReportPaymentStatistics> data = jdbcTemplate.query(SQL + where, new BeanPropertyRowMapper<>(ReportPaymentStatistics.class), args.toArray());

        List<ReportPaymentStatisticsVO> resultdata = new ArrayList<>();
        //封装缴费展示数据
        for (ReportPaymentStatistics d : data) {
            ReportPaymentStatisticsVO v = new ReportPaymentStatisticsVO();
            BeanUtils.copyProperties(d, v);
            String moth = d.getStatDate().substring(4, 6);
            String day = d.getStatDate().substring(6);
            v.setStatDate(moth + "月" + day + "日");
            //DataConversionUtil.fenToYuan 将分转为元
            v.setAlreadyPayAmount(DataConversionUtil.fenToYuan(d.getAlreadyPayAmount().toString()));
            v.setNormalPaymentAmount(DataConversionUtil.fenToYuan(d.getNormalPaymentAmount().toString()));
            v.setOverduePaymentAmount(DataConversionUtil.fenToYuan(d.getOverduePaymentAmount().toString()));
            v.setOverdueAlreadyAmount(DataConversionUtil.fenToYuan(d.getOverdueAlreadyAmount() == null ? "0" : d.getOverdueAlreadyAmount().toString()));
            resultdata.add(v);
        }

        //月份已缴费金额
        BigDecimal monthAlreadyPayAmount = new BigDecimal(0);
        Optional<Integer> monthAlreadyPayAmountOptional = data.stream().map(ReportPaymentStatistics::getAlreadyPayAmount).reduce(Integer::sum);
        if (monthAlreadyPayAmountOptional.isPresent()) {
            monthAlreadyPayAmount = new BigDecimal(monthAlreadyPayAmountOptional.get());
        }

        //月份正常缴费金额
        BigDecimal monthNormalPaymentAmount = new BigDecimal(0);
        Optional<Integer> monthNormalPaymentAmountOptional = data.stream().map(ReportPaymentStatistics::getNormalPaymentAmount).reduce(Integer::sum);
        if (monthNormalPaymentAmountOptional.isPresent()) {
            monthNormalPaymentAmount = new BigDecimal(monthNormalPaymentAmountOptional.get());
        }

        //月份逾期未缴费金额
        BigDecimal monthOverduePaymentAmount = new BigDecimal(0);
        Optional<Integer> monthOverduePaymentAmountOptional = data.stream().map(ReportPaymentStatistics::getOverduePaymentAmount).reduce(Integer::sum);
        if (monthOverduePaymentAmountOptional.isPresent()) {
            monthOverduePaymentAmount = new BigDecimal(monthOverduePaymentAmountOptional.get());
        }

        //月份逾期已缴费金额
        BigDecimal monthOverdueAlreadyAmount = new BigDecimal(0);
        Optional<Integer> monthOverdueAlreadyAmountOptional = data.stream().filter(c -> c.getOverdueAlreadyAmount() != null).map(ReportPaymentStatistics::getOverdueAlreadyAmount).reduce(Integer::sum);
        if (monthOverdueAlreadyAmountOptional.isPresent()) {
            monthOverdueAlreadyAmount = new BigDecimal(monthOverdueAlreadyAmountOptional.get());
        }

        //总额
        BigDecimal totalAmount = new BigDecimal(0);
        totalAmount = monthAlreadyPayAmount.add(monthNormalPaymentAmount).add(monthOverduePaymentAmount).add(monthOverdueAlreadyAmount);

        map.put("monthAlreadyPayAmount", DataConversionUtil.fenToYuan(monthAlreadyPayAmount.toString()));
        map.put("monthNormalPaymentAmount", DataConversionUtil.fenToYuan(monthNormalPaymentAmount.toString()));
        map.put("monthOverduePaymentAmount", DataConversionUtil.fenToYuan(monthOverduePaymentAmount.toString()));
        map.put("monthOverdueAlreadyAmount", DataConversionUtil.fenToYuan(monthOverdueAlreadyAmount.toString()));
        map.put("totalAmount", DataConversionUtil.fenToYuan(totalAmount.toString()));

        map.put("data", resultdata);
        //map.put("total",total);

        return ResultBean.successfulResult(map);
    }


}
